package com.zzh.heart.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;


import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * Created by haodai on 17/8/17.
 */

public class HeartView extends View {


    //控件的长度
    private int width;
    //控件的高度
    private int height;
    //对应的画笔
    private Paint mPaint;
    //绘制用的路径 统一一个
    private Path mPath;
    //变动率
    private float changeRate = 6f;
    //big心 变动率
    private float bigRate;
    //最小变动率
    private float minRate = 5f;
    //跳动率
    private float skipRate = 1.2f;
    //恢复原来大小
    private float defaulRate = 1.0f;
    //相对于中心点上下基数
    private float baseTopAndbottom = 5;
    //相对于中心点 左右基数
    private float baseLiftAndBottom = 14;
    //相对于中心点 上偏移基数
    private float baseOffsetTop = 12;
    //中心坐标点集合
    private List<float[]> points;


    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            invalidate();
        }
    };


    public HeartView(Context context) {
        this(context, null);
    }

    public HeartView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public HeartView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }


    private void init() {
        this.mPaint = new Paint();
        this.mPaint.setAntiAlias(true);
        this.mPaint.setDither(true);
        this.mPaint.setColor(Color.RED);
        this.mPaint.setStrokeWidth(5);
        this.mPaint.setStyle(Paint.Style.FILL);
        this.mPath = new Path();
        this.points = new ArrayList<>();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawHeart(canvas);
        drawChildHeats(canvas);
        Message message = handler.obtainMessage();
        handler.sendMessageDelayed(message, 20);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        this.width = getMeasuredWidth();
        this.height = getMeasuredHeight();
        this.bigRate = this.height / 4f / 14;
        if (this.width != 0 && points.size() <= 0)
            points(20);
    }

    //绘制心形
    private boolean isStatus = true;
    private float changValue = skipRate;

    private void drawHeart(Canvas canvas) {
        if (isStatus) {
            changValue = defaulRate;
            isStatus = false;
        } else {
            changValue = skipRate;
            isStatus = true;
        }
        mPaint.setColor(Color.BLUE);
        mPath.moveTo(this.width / 2, this.height / 2 - 5 * bigRate * changValue);
        mPath.quadTo(this.width / 2 - 14 * bigRate * changValue
                , this.height / 2 - 12 * bigRate * changValue
                , this.width / 2
                , this.height / 2 + 5 * bigRate * changValue);
        canvas.drawPath(mPath, mPaint);
        mPath.reset();
        mPath.moveTo(this.width / 2, this.height / 2 - 5 * bigRate * changValue);
        mPath.quadTo(this.width / 2 + 14 * bigRate * changValue
                , this.height / 2 - 12 * bigRate * changValue
                , this.width / 2
                , this.height / 2 + 5 * bigRate * changValue);
        canvas.drawPath(mPath, mPaint);
    }

    //绘制孩子们
    private void drawChildHeats(Canvas canvas) {
        mPaint.setColor(Color.RED);
        for (int i = 0; i < points.size(); i++) {
            mPath.reset();
            float[] child = points.get(i);
            child[1] = child[1] / child[2];
            if (child[1] < this.height / 3 * 2)
                child[1] = child[1] / child[2];
            child[0] = (int) child[1] % 2 > 0 ? child[0] / child[2] : child[0] * child[2];
            child = toDealWithXAndY(child);
            float skipRate = child[0] % 2 > 0 ? this.skipRate : this.defaulRate;

            mPath.moveTo(child[0], child[1] - baseTopAndbottom * changeRate);
            mPath.quadTo(child[0] - baseLiftAndBottom * changeRate * skipRate
                    , child[1] - baseOffsetTop * changeRate * skipRate
                    , child[0]
                    , child[1] + baseTopAndbottom * changeRate * skipRate);
            canvas.drawPath(mPath, mPaint);
            mPath.reset();
            mPath.moveTo(child[0], child[1] - baseTopAndbottom * changeRate);
            mPath.quadTo(child[0] + baseLiftAndBottom * changeRate * skipRate
                    , child[1] - baseOffsetTop * changeRate * skipRate
                    , child[0]
                    , child[1] + baseTopAndbottom * changeRate * skipRate);
            canvas.drawPath(mPath, mPaint);
        }
    }

    //处理x y值
    private float[] toDealWithXAndY(float[] value) {
        if (value[0] < baseLiftAndBottom * minRate * skipRate ||
                value[0] > this.width - baseLiftAndBottom * minRate * skipRate ||
                value[1] < baseOffsetTop * minRate * skipRate ||
                value[1] > this.height - baseTopAndbottom * minRate * skipRate) {
            float values[] = creatPoints();
            value[0] = values[0];
            value[1] = values[1];
            value[2] = values[2];
        }
        return value;
    }


    /*************************
     * 测试数据区
     *************************************/
    //生成心集合集合
    private void points(int count) {
        for (int i = 0; i < count; i++) {
            float[] child = creatPoints();
            points.add(child);
        }
    }

    private float[] creatPoints() {
        int x = getRandomValue((int) (this.width - baseLiftAndBottom * minRate * skipRate),
                (int) (baseLiftAndBottom * minRate * skipRate));
        int y = getRandomValue((int) (this.height - baseTopAndbottom * minRate * skipRate),
                (int) (this.height - baseTopAndbottom * minRate * skipRate) / 5 * 4);
        float rate = getRandomValue() / 50;
        float[] child = {
                x, y, rate + 1
        };
        return child;
    }


    /**************************************************************/
    //随机数 int
    private int getRandomValue(int max, int min) {
        Random r = new Random();
        return r.nextInt(max) % (max - min + 1) + min;
    }

    //随机数
    private float getRandomValue() {
        Random r = new Random();
        return r.nextFloat();
    }

}
